home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Files / XTND 1.3.6 / Translator Examples / MacWrite Translator / MacWriteImport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-23  |  27.4 KB  |  854 lines  |  [TEXT/MPS ]

  1. /************************************************************************
  2. *                                                                        *
  3. *    MacWriteImport.c                                                    *
  4. *                                                                        *
  5. *    Translator for reading a MacWrite file with XTND 1.3.                *
  6. *                                                                        *
  7. *    Copyright © 1989,90 Claris Corporation                                *
  8. *    All Rights Reserved                                                    *
  9. *                                                                        *
  10. *    Author: Richard Scorer                                                *
  11. *    Date:   13 April, 1988                                                *
  12. *                                                                        *
  13. ************************************************************************/
  14.  
  15. #include <Printing.h>
  16. #include <Resources.h>
  17. #include <Fonts.h>
  18. #include <Memory.h>
  19. #include <StandardFile.h>
  20. #include "CodeA5Globals.h"
  21. enum { FALSE, TRUE };
  22.  
  23. #ifndef THINK_C
  24. #include "CodeA5Globals.h"
  25. #endif
  26.  
  27. #include ":::XTND Headers:XTNDCIncludes:XTNDTextTranslator.h"
  28.  
  29. #include "MacWrite.h"                    /* MacWrite 5.0 specific header */
  30.  
  31.  
  32. /*------------------------- Useful Constants ---------------------------*/
  33.  
  34. /* version number of MacWrite that this translator recognizes */
  35. #define kValidVersionNum    6
  36.  
  37. /*----------State defines----------*/
  38. #define kInitial 0
  39. #define kNewSrch 1
  40. #define kSameSrch 2
  41.  
  42.  
  43. /*-------------------------Global Variables-----------------------------*/
  44.  
  45. static ImportParmBlkPtr    gImportPBPtr;
  46. static MacWriteHeader    *MWHeader;                /* File header */
  47.  
  48. /*                         paragraph info pointers                        */
  49. static unsigned char    *gParagPtr, *gParagraph, *gParagPos;
  50. unsigned char            *gCurrentFormat;
  51. static short            gParagDLent;
  52. static Boolean            gDidPicture;                /* Indicator for PICT gParagraph */
  53. static unsigned char    gCompressChars[15];        /* Compression string */
  54. static unsigned char    gDefaultChars[16] = " etnroaisdlhcfp";
  55. static InfoStruct        *gInfoArray;                /* */
  56. static MacWriteWindow    gTheWindow;                /* Document window buffer */
  57. static short            gParagCount;                /* Total number of gParagraphs */
  58. static Fixed            gSavePara[numParaFmts];        /*    */
  59. static Fixed            gSaveTab;                /* */
  60. static Fixed            gMarginWidth;            /* */
  61. static Boolean            gFoundString = FALSE;    /* Compresson string resource found? */
  62.  
  63.  
  64. /*-------------------------Function prototypes--------------------------*/
  65.  
  66.         void    main(ImportParmBlkPtr);
  67. static    Boolean    ValidApplHandle(Handle h);
  68. static    void    ImportMacWrite(ImportParmBlkPtr);
  69. static    void    GetResources(void);
  70. static    long    InitAll(void);
  71. static    long    InitStory(void);
  72. static    void    DecompressData(void);
  73. static    Boolean    GetPict(InfoStruct *);
  74. static    Boolean    CheckPageBreak(InfoStruct *);
  75. static    void    CreateParagraph(InfoStruct *, short *, short *, short *, short *, short *, short);
  76. static    void    GetRulerInfo(InfoStruct *, short *);
  77. static    short    GetMacWriteData(void);
  78. static    void    CleanUp(void);
  79.  
  80.  
  81. /*----------------------------------------------------------------------*/
  82. /*                                                                        */
  83. /*    main    This is the main routine and the only entry point for the    */
  84. /*            the translator.                                                */
  85. /*    NOTE: This translator uses globals that are used from the first to    */
  86. /*    last call. The first call should be with the IMPORT_GET_RESOURCES    */
  87. /*    directive, at which time the globals will be allocated. However, if    */
  88. /*    for some reason the application does not make the first call with    */
  89. /*    the IMPORT_GET_RESOURCES directive then the translator must            */
  90. /*    allocate the globals when it receives the IMPORT_INIT_ALL            */
  91. /*    directive. The rub is that there is no way to know for sure if the    */
  92. /*    globals have already been allocated. So we do the best that we can    */
  93. /*    by simply testing to see if the GlobalHandle field of the import    */
  94. /*    parameter block contains what appears to be a valid handle. Note to    */
  95. /*    this note: this note does NOT apply if you are using Think C’s        */
  96. /*    A4-based globals.                                                    */
  97. /*                                                                        */
  98. /*----------------------------------------------------------------------*/
  99. void main(importParamPtr)
  100. ImportParmBlkPtr importParamPtr;
  101. {
  102. #ifdef THINK_C
  103.     asm {
  104.         move.l    a4,-(sp)
  105.         move.l    a0,a4                ; Sets up the globals for this CODE
  106.     }
  107. #else
  108.     long savedA5;
  109.  
  110.     if (importParamPtr->directive == importGetResources ||
  111.         (importParamPtr->directive == importInitAll &&
  112.         !ValidApplHandle(importParamPtr->globalHandle))) {
  113.         importParamPtr->globalHandle = NewHandle(0L);
  114.         MakeA5World(importParamPtr->globalHandle);
  115.     }
  116.     savedA5 = SetA5World(importParamPtr->globalHandle);
  117. #endif
  118.  
  119.     ImportMacWrite(importParamPtr);
  120.  
  121. #ifdef THINK_C
  122.     asm {
  123.         move.l    (sp)+,a4
  124.     }
  125. #else
  126.     RestoreA5World(savedA5, importParamPtr->globalHandle);
  127.     if (importParamPtr->directive == importCloseAll) {
  128.         DisposeA5World(importParamPtr->globalHandle);
  129.         importParamPtr->globalHandle = NULL;
  130.     }
  131. #endif
  132. }
  133.  
  134.  
  135. #ifndef THINK_C
  136. /*----------------------------------------------------------------------*/
  137. /*                                                                        */
  138. /*    ValidApplHandle attempts to determine if the handle h is a valid    */
  139. /*    handle in the current application zone. It checks to see that h is    */
  140. /*    word aligned, and is within the application zone. It also checks    */
  141. /*    to see if *h is word aligned, and is within the application zone.    */
  142. /*    Finally, it checks to see if RecoverHandle(*h) == h. It returns        */
  143. /*    FALSE as the function return value if any test fails, otherwise it    */
  144. /*    returns TRUE.                                                        */
  145. /*                                                                        */
  146. /*----------------------------------------------------------------------*/
  147. Boolean ValidApplHandle(Handle h)
  148. {
  149.     Ptr p, hiZ, loZ;
  150.  
  151.     if ((unsigned long)h & 1)
  152.         return(FALSE);
  153.     if ((Ptr)h < (loZ = StripAddress(ApplicZone())) || (Ptr)h > (hiZ = StripAddress(GetApplLimit())))
  154.         return(FALSE);
  155.     if ((unsigned long)(p = StripAddress(*h)) & 1)
  156.         return(FALSE);
  157.     if (p < loZ || p > hiZ)
  158.         return(FALSE);
  159.     return(RecoverHandle(p) == h);
  160. }
  161. #endif
  162.  
  163.  
  164. /*----------------------------------------------------------------------*/
  165. /*                                                                        */
  166. /*    ImportMacWrite dispatches the call to the appropriate routine         */
  167. /*  depending on the Directive.                                            */
  168. /*                                                                        */
  169. /*----------------------------------------------------------------------*/
  170. void ImportMacWrite(ImportParmBlkPtr importParamPtr)
  171. {
  172.     gImportPBPtr = importParamPtr;
  173.     
  174.     switch (importParamPtr->directive) {
  175.         case importGetResources:
  176.             GetResources();
  177.             break;
  178.  
  179.         case importInitAll:
  180.             gImportPBPtr->textLength = InitAll();
  181.             break;
  182.  
  183.         case importInitHeader:
  184.         case importInitFooter:
  185.         case importInitMain:
  186.             gImportPBPtr->textLength = InitStory();
  187.             break;
  188.  
  189.         case importGetText:
  190.             gImportPBPtr->textLength = GetMacWriteData();
  191.             break;
  192.  
  193.         case importCloseAll:
  194.             CleanUp();
  195.             break;
  196.         
  197.         default:
  198.             break;
  199.     }
  200. }
  201.  
  202.  
  203. /*----------------------------------------------------------------------*/
  204. /*                                                                        */
  205. /*    GetResources gets all necessary resources from file.  For MacWrite,    */
  206. /*    this means the compression characters.                                */
  207. /*                                                                        */
  208. /*----------------------------------------------------------------------*/
  209. static void GetResources()
  210. {
  211.     register Handle    thechars;
  212.     
  213.     /* read in the compression characters */
  214.     if (thechars = (Handle)GetResource('STR ', 700)) {
  215.         gFoundString = TRUE;
  216.         BlockMove((*thechars) + 1, gCompressChars, 15);
  217.     }
  218.     ReleaseResource(thechars);
  219. }
  220.  
  221.  
  222. /*----------------------------------------------------------------------*/
  223. /*                                                                        */
  224. /*    CleanUp handles clean up after import is finished.                    */
  225. /*    Currently it just disposes of storage.                                */
  226. /*                                                                        */
  227. /*----------------------------------------------------------------------*/
  228. static void CleanUp()
  229. {
  230.     DisposPtr((Ptr)MWHeader);
  231. }
  232.  
  233.  
  234. /*----------------------------------------------------------------------*/
  235. /*                                                                        */
  236. /*    InitAll initializes reading of MacWrite documents.                    */
  237. /*                                                                        */
  238. /*----------------------------------------------------------------------*/
  239. static long InitAll()
  240. {
  241.     long                count;
  242.     register long        rqrdsize;
  243.     Rect                paperRect, pageRect;
  244.  
  245.     /* get compression characters */
  246.     if (!gFoundString)
  247.         BlockMove(gDefaultChars, gCompressChars, 15);
  248.     gFoundString = FALSE;
  249.  
  250.     /* init header */
  251.     MWHeader = (MacWriteHeader *) NewPtr(sizeof(MacWriteHeader));
  252.     if (gImportPBPtr->result = MemError()) return (0);
  253.  
  254.     /* read in the MacWrite header information */
  255.     gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, 0L);
  256.     count = sizeof(MacWriteHeader);
  257.     if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, MWHeader))return (0);
  258.  
  259.     /* Check version number */
  260.     if (MWHeader->versionNo != kValidVersionNum)
  261.     {
  262.         gImportPBPtr->result = badImportFileErr;
  263.         return (0);
  264.     }
  265.  
  266.     /* set up the print record */
  267.     gImportPBPtr->printRecord    = (THPrint)NewHandle(sizeof(TPrint));
  268.     if (gImportPBPtr->result = MemError()) return (0);
  269.     BlockMove(&MWHeader->printRecord, *gImportPBPtr->printRecord, sizeof(TPrint));
  270.     
  271.     /* Sure wish I could validate the print record here...*/
  272.     
  273.     paperRect        = (*(THPrint)gImportPBPtr->printRecord)->rPaper;
  274.     pageRect        = (*(THPrint)gImportPBPtr->printRecord)->prInfo.rPage;
  275.     
  276.     gImportPBPtr->hRes            = (*(THPrint)gImportPBPtr->printRecord)->prInfo.iHRes;
  277.     gImportPBPtr->vRes            = (*(THPrint)gImportPBPtr->printRecord)->prInfo.iVRes;
  278.     gImportPBPtr->topMargin        = (Fixed)(0 - paperRect.top) << 16;
  279.     gImportPBPtr->leftMargin        = (Fixed)(gImportPBPtr->hRes) << 16;            /* 1 inch */
  280.     gImportPBPtr->bottomMargin    = (Fixed)(paperRect.bottom - pageRect.bottom) << 16;
  281.     gImportPBPtr->rightMargin    = (Fixed)(paperRect.right - pageRect.right) << 16;
  282.  
  283.     gMarginWidth = ((long)paperRect.right - paperRect.left) << 16;
  284.  
  285.     /* set up the default information for the document */
  286.     gImportPBPtr->autoHyphenate    = FALSE;
  287.     gImportPBPtr->startPageNum    = MWHeader->startPageNum;
  288.     gImportPBPtr->rulerShowing    = !MWHeader->rulersHidden;
  289.     gImportPBPtr->doubleSided        = FALSE;
  290.     gImportPBPtr->titlePage        = MWHeader->titlePage;
  291.     gImportPBPtr->showInvisibles    = FALSE;
  292.     gImportPBPtr->showPageGuides    = FALSE;
  293.     gImportPBPtr->showPictures    = TRUE;
  294.     
  295.     /* subtract width of margins */
  296.     gMarginWidth -= (gImportPBPtr->leftMargin + gImportPBPtr->rightMargin);
  297.     
  298.     gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, 0L);
  299.     rqrdsize = 0;
  300.     gImportPBPtr->translatorState = kInitial;
  301.     gDidPicture = FALSE;
  302.     return (rqrdsize);
  303. }
  304.  
  305.  
  306. /*----------------------------------------------------------------------*/
  307. /*                                                                        */
  308. /*    InitStory initializes the reading of headers, footers, main.        */
  309. /*                                                                        */
  310. /*----------------------------------------------------------------------*/
  311. static long InitStory()
  312. {
  313.     long count = 0;
  314.  
  315.     /* see if we have the requested item (header, footer, etc.) */
  316.     switch (gImportPBPtr->currentStory)
  317.     {
  318.         case headerStory:
  319.             if (MWHeader->headerDisplay)
  320.             {
  321.                 gImportPBPtr->directive = importAcknowledge;
  322.                 count = 206L;
  323.                 gParagCount = MWHeader->headerPars;
  324.             }
  325.             break;
  326.             
  327.         case footerStory:
  328.             if (MWHeader->footerDisplay)
  329.             {
  330.                 gImportPBPtr->directive = importAcknowledge;
  331.                 count = 160L;
  332.                 gParagCount = MWHeader->footerPars;
  333.             }
  334.             break;
  335.             
  336.         case mainStory:
  337.             gImportPBPtr->directive = importAcknowledge;
  338.             count = 252L;
  339.             gParagCount = MWHeader->mainPars;
  340.             break;
  341.     }
  342.  
  343.     if (count) {
  344.         if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, count))
  345.             return(0);
  346.         
  347.         /* read in the window information */
  348.         count = sizeof(MacWriteWindow);
  349.         if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, &gTheWindow))
  350.             return(0);
  351.             
  352.         /* read in the information array */
  353.         gInfoArray = (InfoStruct *)NewPtr((long)gTheWindow.infoAryLength);
  354.         if (gImportPBPtr->result = MemError())
  355.             return(0);
  356.     
  357.         if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, gTheWindow.infoAryPos))
  358.             return(0);
  359.         count = gTheWindow.infoAryLength;
  360.         if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, gInfoArray))
  361.             return(0);
  362.  
  363.         /* Autogrow the headers and footers */
  364.         gImportPBPtr->storyHeight = 0;
  365.         if (gImportPBPtr->currentStory != mainStory) {
  366.             /* set up page, date, and time information */
  367.             gImportPBPtr->pagePoint = *(Point *)&gTheWindow.pageNumPos;
  368.             gImportPBPtr->datePoint = *(Point *)&gTheWindow.datePos;
  369.             gImportPBPtr->timePoint = *(Point *)&gTheWindow.timePos;
  370.         }
  371.     }
  372.             
  373.     gImportPBPtr->translatorState = kInitial;
  374.     gDidPicture = FALSE;
  375.     return(0);
  376. }
  377.  
  378.  
  379. /*----------------------------------------------------------------------*/
  380. /*                                                                        */
  381. /*    DecompressData decompresses the data as it is read in from the         */
  382. /*    MacWrite file.                                                        */
  383. /*                                                                        */
  384. /*----------------------------------------------------------------------*/
  385. static void DecompressData()
  386. {
  387.     register unsigned char    *dcompar, *dcomparpos, *chk1buf, *chk2buf;
  388.     unsigned char            leftnibl, rightnibl;
  389.     unsigned char            *tmpfrmtpos, *tmpptr;
  390.     register short            frmtlent, i;
  391.     
  392.     dcompar = (unsigned char *)NewPtr((long) gParagDLent);
  393.     if (gImportPBPtr->result = MemError()) return;
  394.     dcomparpos = dcompar;
  395.     for (; (dcomparpos - dcompar) < (long) gParagDLent; gParagPos++) {
  396.         leftnibl = (*gParagPos & 0xF0) >> 4;
  397.         rightnibl = *gParagPos & 0x0F;
  398.         if (leftnibl == 0x0F) {
  399.             *dcomparpos++ = (rightnibl << 4) | ((*(++gParagPos) & 0xF0) >> 4);
  400.             if ((dcomparpos - dcompar) == (long) gParagDLent) continue;
  401.             rightnibl = *gParagPos & 0x0F;
  402.         }
  403.         else *dcomparpos++ = gCompressChars[leftnibl];
  404.         if (rightnibl == 0x0F) *dcomparpos++ = *(++gParagPos);
  405.         else *dcomparpos++ = gCompressChars[rightnibl];
  406.     }
  407.     gCurrentFormat = gParagPos + ((gParagPos - gParagraph) & 1);
  408.     frmtlent = *(short *)gCurrentFormat;
  409.     tmpptr = (unsigned char *)NewPtr((long)gParagDLent + frmtlent + 2L);
  410.     if (gImportPBPtr->result = MemError()) return;
  411.     chk1buf = tmpptr;
  412.     chk2buf = dcompar;
  413.     for (i = 0; i < gParagDLent; i++) *chk1buf++ = *chk2buf++;
  414.     if (gParagDLent & 1) *chk1buf++ = 0x00;
  415.     tmpfrmtpos = chk1buf;
  416.     chk2buf = gCurrentFormat;
  417.     for (i = 0; i < frmtlent + 2; i++) *chk1buf++ = *chk2buf++;
  418.     if (gParagPtr)
  419.     {
  420.         DisposPtr((Ptr)gParagPtr);
  421.         gParagPtr = 0;
  422.     }
  423.     DisposPtr((Ptr)dcompar);
  424.     gParagPtr = gParagraph = tmpptr;
  425.     gParagPos = gParagraph;
  426.     gCurrentFormat = tmpfrmtpos;
  427. }
  428.  
  429.  
  430. /*----------------------------------------------------------------------*/
  431. /*                                                                        */
  432. /*    GetPict attempts to read in a MacWrite picture.                        */
  433. /*                                                                        */
  434. /*----------------------------------------------------------------------*/
  435. static Boolean GetPict(infoitem)
  436. register InfoStruct *infoitem;
  437. {
  438.     long                        count;
  439.     register PictMisc            **pmisc;
  440.     PictureParagraph            theParagraph;
  441.     register PicHandle            thePicture;
  442.     
  443.     if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, infoitem->Status.paraFilePosn)) return (FALSE);
  444.     count = (long) sizeof(PictureParagraph);
  445.     if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, &theParagraph)) return (FALSE);
  446.     count = (long) theParagraph.thePicture.picSize;
  447.     
  448.     /* read in the picture */
  449.     thePicture = (PicHandle) NewHandle((Size)count);
  450.     if (gImportPBPtr->result = MemError()) return (FALSE);
  451.     if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, infoitem->Status.paraFilePosn + 8)) return (FALSE);
  452.     HLock((Handle)thePicture);
  453.     if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, *thePicture)) return (FALSE);
  454.     HUnlock((Handle)thePicture);
  455.     
  456.     /* set up the miscdata */
  457.     pmisc = (PictMisc **)NewHandle(sizeof(PictMisc));
  458.     if (gImportPBPtr->result = MemError())
  459.     {
  460.         DisposHandle((Handle)thePicture);
  461.         return (FALSE);
  462.     }
  463.     (*pmisc)->thePicture = thePicture;
  464.     (*pmisc)->pictSize = count;
  465.     (*pmisc)->destRect = theParagraph.pictureSize;
  466.     (*pmisc)->origRect = (*thePicture)->picFrame;
  467.     gImportPBPtr->miscData = (long) pmisc;
  468.     /* set up left indent so that picture is in the right place */
  469.     gImportPBPtr->paraFmts[0] = (long)theParagraph.pictureSize.left << 16;
  470.     gImportPBPtr->paraFmts[1] = 0L;
  471.     gImportPBPtr->tabs[0].tabIndent = -1L;
  472.     return (TRUE); 
  473. }
  474.  
  475.  
  476. /*----------------------------------------------------------------------*/
  477. /*                                                                        */
  478. /*    CheckPageBreak checks the page breaks, and returns them as 0x0C.    */
  479. /*                                                                        */
  480. /*----------------------------------------------------------------------*/
  481. static Boolean CheckPageBreak(InfoStruct *infoitem)
  482. {
  483.     long count;
  484.     Rect picturerect;
  485.     PictureParagraph theParagraph;
  486.     
  487.     if (infoitem->paraLen <= 18) return
  488.         (FALSE);
  489.     if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, infoitem->Status.paraFilePosn))
  490.         return(FALSE);
  491.     count = (long)sizeof(PictureParagraph);
  492.     if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, &theParagraph))
  493.         return(FALSE);
  494.     picturerect = theParagraph.thePicture.picFrame;
  495.     if ( picturerect.top    == 'MA' &&
  496.          picturerect.left    == 'GI' &&
  497.          picturerect.bottom    == 'CP' &&
  498.          picturerect.right    == 'IC')
  499.         return (TRUE);
  500.     else
  501.         return (FALSE);
  502. }
  503.  
  504.  
  505. /*----------------------------------------------------------------------*/
  506. /*                                                                        */
  507. /*    CreateParagraph creates a gParagraph.                                */
  508. /*                                                                        */
  509. /*----------------------------------------------------------------------*/
  510. static void CreateParagraph(infoitem, frmtlent, frmtcnt, curface, cursize, curfont, justfctn) 
  511. register InfoStruct        *infoitem;
  512. register short            *frmtlent, *frmtcnt;
  513. short                    *curface, *cursize, *curfont, justfctn;
  514. {
  515. #define COMPBITMASK 0x08            /* if this bit is set, the text is compressed */
  516. #define JUSTBITMASK 0x40            /* if this bit is set, use the parag just, not ruler */
  517. #define JUSTCODEMASK 0x03            /* the justification code for this gParagraph */
  518.  
  519.     long    count;
  520.     
  521.     if ((infoitem->Status.justCode) & JUSTBITMASK)
  522.         gImportPBPtr->txtJust = (short) ((infoitem->Status.justCode) & JUSTCODEMASK);
  523.     else
  524.         gImportPBPtr->txtJust = justfctn;
  525.     
  526.     if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, infoitem->Status.paraFilePosn)) return;
  527.     count = (long) infoitem->paraLen;
  528.     gParagPtr = gParagraph = (unsigned char *)NewPtr((long) count);
  529.  
  530.     if (gImportPBPtr->result = MemError()) return;
  531.     if (gImportPBPtr->result = FSRead(gImportPBPtr->refNum, &count, gParagraph)) return;
  532.  
  533.     gParagDLent = *(short *)gParagraph;
  534.     gParagraph += 2;
  535.     gParagPos = gParagraph;
  536.     gCurrentFormat = gParagPos + gParagDLent + (gParagDLent & 1);
  537.  
  538.     /* if necessary, decompress data */
  539.     if ((infoitem->Status.justCode) & COMPBITMASK) DecompressData();
  540.  
  541.     *frmtlent = *(short *)gCurrentFormat;
  542.     gCurrentFormat += 4;
  543.     *frmtcnt = 0;
  544.     *cursize = (short) *gCurrentFormat++;
  545.     *curface = (short) *gCurrentFormat++;
  546.     *curfont = *(short *)gCurrentFormat;
  547.     gCurrentFormat += 2;
  548. }
  549.  
  550.  
  551. /*----------------------------------------------------------------------*/
  552. /*                                                                        */
  553. /*    GetRulerInfo gets the gParagraph information from ruler.                */
  554. /*                                                                        */
  555. /*----------------------------------------------------------------------*/
  556. static void GetRulerInfo(infoitem, justfctn) 
  557. register InfoStruct    *infoitem;
  558. short                *justfctn;
  559. {
  560.     long            count;
  561.     RulerParagraph    theParagraph;
  562.     register short    i;
  563.     register Fixed    tabValue;
  564.  
  565.     gImportPBPtr->txtJust = textLeft;
  566.  
  567.     for (i = 0; i < numParaFmts; i++) gImportPBPtr->paraFmts[i] = 0;
  568.     for (i = 0; i < maxTabs; i++) gImportPBPtr->tabs[i].tabIndent = -1;
  569.  
  570.     if (gImportPBPtr->result = SetFPos(gImportPBPtr->refNum, fsFromStart, infoitem->Status.paraFilePosn)) return;
  571.  
  572.     count = (long) sizeof(RulerParagraph);
  573.     if (FSRead(gImportPBPtr->refNum, &count, &theParagraph)) return;
  574.  
  575.     gImportPBPtr->paraFmts[0] = (Fixed)theParagraph.leftMargin << 16;
  576.     gImportPBPtr->paraFmts[1] = ((Fixed)theParagraph.lineIndent << 16) - gImportPBPtr->paraFmts[0];
  577.     gImportPBPtr->paraFmts[2] = gMarginWidth - ((Fixed)theParagraph.rightMargin << 16);
  578.  
  579.     /* adjust for 1/16 measurements */
  580.     for (i = 0;i<3;i++) {
  581.         if ((((gImportPBPtr->paraFmts[i] >> 16) % 72) - 4) % 9 == 0)
  582.             gImportPBPtr->paraFmts[i] += 0x8000;
  583.     }
  584.  
  585.     if (gImportPBPtr->paraFmts[0] < 0) gImportPBPtr->paraFmts[0] = 0;
  586.     if (gImportPBPtr->paraFmts[0] + gImportPBPtr->paraFmts[1] < 0) gImportPBPtr->paraFmts[1] = gImportPBPtr->paraFmts[0];
  587.     if (gImportPBPtr->paraFmts[2] < 0) gImportPBPtr->paraFmts[2] = 0;
  588.  
  589.     gImportPBPtr->txtJust = *justfctn = (short) theParagraph.justification;
  590.     if (theParagraph.lineSpacing & 0x8000) {
  591.         gImportPBPtr->paraFmts[6] = 0L;
  592.         /* the six lines per inch madness is active */
  593.         switch (theParagraph.lineSpacing & 0x00FF) {
  594.             case 0:  gImportPBPtr->paraFmts[3] = (long)12 << 16;    break;
  595.             case 1:  gImportPBPtr->paraFmts[3] = (long)18 << 16;    break;
  596.             case 2:     gImportPBPtr->paraFmts[3] = (long)24 << 16;    break;
  597.             default: gImportPBPtr->paraFmts[3] = (long)12 << 16;    break;
  598.         }
  599.     } else {
  600.         gImportPBPtr->paraFmts[6] = -1L;
  601.         switch (theParagraph.lineSpacing & 0x00FF) {
  602.             case 0:  gImportPBPtr->paraFmts[3] = 0L;            break;    /* single line spacing */
  603.             case 1:  gImportPBPtr->paraFmts[3] = 0x08000;    break;    /* 1 1/2 line spacing */
  604.             case 2:  gImportPBPtr->paraFmts[3] = 0x10000;    break;    /* double line spacing */
  605.             default: gImportPBPtr->paraFmts[3] = 0L;            break;    /* single line spacing */
  606.         }
  607.     }
  608.     
  609.     for (i = 0; i < theParagraph.numTabs; i++) {
  610.         tabValue = theParagraph.tabArray[i];
  611.         if (tabValue < 0) {
  612.             gImportPBPtr->tabs[i].tabJust = textDecimal;
  613.             tabValue = -tabValue;
  614.         } else
  615.             gImportPBPtr->tabs[i].tabJust = textLeft;
  616.             
  617.         gImportPBPtr->tabs[i].tabLead = ' ';
  618.         gImportPBPtr->tabs[i].tabIndent = (Fixed)tabValue << 16;
  619.  
  620.         /* adjust for 1/16 measurements */
  621.         if (((tabValue % 72) - 4) % 9 == 0)
  622.             gImportPBPtr->tabs[i].tabIndent += 0x8000;
  623.     }
  624.  
  625.     /* save this information in case we have to change it for a gParagraph */
  626.     for (i = 0; i < numParaFmts; i++) gSavePara[i] = gImportPBPtr->paraFmts[i];
  627.     gSaveTab = gImportPBPtr->tabs[0].tabIndent;
  628. }
  629.  
  630.  
  631. /*----------------------------------------------------------------------*/
  632. /*                                                                        */
  633. /*    GetMacWriteData reads the text in from the MacWrite file.            */
  634. /*                                                                        */
  635. /*----------------------------------------------------------------------*/
  636. static short GetMacWriteData()
  637. {
  638.     register short            *face = &gImportPBPtr->txtFace,
  639.                             *size = &gImportPBPtr->txtSize,
  640.                             *font = &gImportPBPtr->txtFont,
  641.                             paraghit;
  642.     short                    i;
  643.     InfoStruct                *infoitem;
  644.  
  645.     static short            infoindex;
  646.     static short            cursize, curface, curfont;
  647.     static short            frmtlent, frmtcnt, justfctn;
  648.     static long                srchlmt;
  649.     static Ptr                tmpstrpos;
  650.  
  651.     gImportPBPtr->txtColor = textBlack;
  652.  
  653.     switch (gImportPBPtr->translatorState)
  654.     {
  655.         case kInitial:
  656.             gParagPtr = (unsigned char *) 0;
  657.             
  658.             /* Set up initial ruler information */
  659.             for (infoindex = 0, paraghit = 0; ((paraghit == 0) && (infoindex < gParagCount)); infoindex++)
  660.             {
  661.                 infoitem = &gInfoArray[infoindex];
  662.                 paraghit = infoitem->paraHeight;
  663.                 if (paraghit == 0) {
  664.                     GetRulerInfo(infoitem, &justfctn);
  665.                     if (gImportPBPtr->result) return (0);
  666.                 }
  667.             }
  668.             if (paraghit == 0) {
  669.                 /* There is no text in this MacWrite document.  return 0. */
  670.                 DisposPtr((Ptr)gInfoArray);
  671.                 gImportPBPtr->directive = importAcknowledge;
  672.                 return (0);
  673.             }
  674.             if (paraghit < 0) {
  675.                 /* This is a picture gParagraph. */
  676.                 gParagDLent = srchlmt = 0L;
  677.                 gImportPBPtr->translatorState = kNewSrch;
  678.                 *size = 12;
  679.                 *face = textPlain;
  680.                 *font = geneva;
  681.  
  682.                 /* Check to see if this a page break gParagraph. */
  683.                 if (CheckPageBreak(infoitem)) {
  684.                     *gImportPBPtr->textBuffer = 0x0C;
  685.                     return (1); 
  686.                 } else {         
  687.                     /* Attempt to read in the picture. */
  688.                     if (GetPict(infoitem)) {
  689.                         *gImportPBPtr->textBuffer = floatingPict;
  690.                         gDidPicture = TRUE;
  691.                         /* make sure gParagraph is single spaced */
  692.                         gImportPBPtr->paraFmts[6] = -1L;
  693.                         gImportPBPtr->paraFmts[3] = 0L;
  694.                         return (1); 
  695.                     } else {
  696.                         gImportPBPtr->directive = importAcknowledge;
  697.                         return (0);
  698.                     }
  699.                 }
  700.             }
  701.             /* We now know this is a text gParagraph. */
  702.             CreateParagraph(infoitem, &frmtlent, &frmtcnt, &curface,
  703.                 &cursize, &curfont, justfctn);
  704.             if (gImportPBPtr->result) return (0); 
  705.  
  706.             if (frmtlent == (frmtcnt + 1) * 6) 
  707.                 srchlmt = (long)gParagDLent;
  708.             else {
  709.                 srchlmt = (long) *(short *)gCurrentFormat;
  710.                 gCurrentFormat += 2;
  711.             }
  712.             tmpstrpos = gImportPBPtr->textBuffer;
  713.             for (; ((tmpstrpos - gImportPBPtr->textBuffer) < (long)256 ) && 
  714.                                                 ((gParagPos - gParagraph) < srchlmt);)
  715.                 *tmpstrpos++ = *gParagPos++;
  716.  
  717.             if ((gParagPos - gParagraph) == srchlmt) 
  718.                 gImportPBPtr->translatorState = kNewSrch;
  719.             else 
  720.                 gImportPBPtr->translatorState = kSameSrch;
  721.             *size = cursize;
  722.             *face = curface;
  723.             *font = curfont;
  724.             return ((short)(tmpstrpos - gImportPBPtr->textBuffer)); 
  725.             break;
  726.  
  727.         case kNewSrch:
  728.             if (gDidPicture) {
  729.                 /* A picture was inserted.  Put a return character in. */
  730.                 *size = 12;
  731.                 *face = textPlain;
  732.                 *font = geneva;
  733.                 gParagDLent = 0;
  734.                 srchlmt = (long)gParagDLent;
  735.                 gImportPBPtr->translatorState = kNewSrch;
  736.                 *gImportPBPtr->textBuffer = returnChar;
  737.                 gDidPicture = FALSE;
  738.                 return (1); 
  739.             } else {
  740.                 for (i = 0; i < numParaFmts; i++) 
  741.                     gImportPBPtr->paraFmts[i] = gSavePara[i];
  742.                 gImportPBPtr->tabs[0].tabIndent = gSaveTab;
  743.             }
  744.             if (srchlmt == (long)gParagDLent) {
  745.                 if (gParagPtr) {
  746.                     DisposPtr((Ptr)gParagPtr);
  747.                     gParagPtr = 0;
  748.                 }
  749.                 for (paraghit = 0;((paraghit == 0) && (infoindex < gParagCount)); infoindex++)
  750.                 {
  751.                     infoitem = &gInfoArray[infoindex];
  752.                     paraghit = infoitem->paraHeight;
  753.                     if (paraghit == 0) {
  754.                         GetRulerInfo(infoitem, &justfctn);
  755.                         if (gImportPBPtr->result) return (0);
  756.                     }
  757.                 }
  758.                 if (paraghit == 0) {
  759.                     DisposPtr((Ptr)gInfoArray);
  760.                     gImportPBPtr->directive = importAcknowledge;
  761.                     return (0);
  762.                 }
  763.                 if (paraghit < 0) {
  764.                     /* This is a picture gParagraph. */
  765.                     gParagDLent = 0;
  766.                     srchlmt = (long)gParagDLent;
  767.                     gImportPBPtr->translatorState = kNewSrch;
  768.                     *size = 12;
  769.                     *face = textPlain;
  770.                     *font = geneva;
  771.  
  772.                     /* Check to see if this a page break gParagraph. */
  773.                     if (CheckPageBreak(infoitem)) {
  774.                         *gImportPBPtr->textBuffer = 0x0C;
  775.                         return (1); 
  776.                     } else {
  777.                         if (GetPict(infoitem)) {
  778.                             /* Attempt to read in the picture. */
  779.                             *gImportPBPtr->textBuffer = floatingPict;
  780.                             gDidPicture = TRUE;
  781.                             /* make sure gParagraph is single spaced */
  782.                             gImportPBPtr->paraFmts[6] = -1L;
  783.                             gImportPBPtr->paraFmts[3] = 0L;
  784.                             return (1); 
  785.                         } else {
  786.                             gImportPBPtr->directive = importAcknowledge;
  787.                             return (0);
  788.                         }
  789.                     }
  790.                 }
  791.                 /* We now know this is a text gParagraph. */
  792.                 CreateParagraph(infoitem, &frmtlent, &frmtcnt, &curface,
  793.                                             &cursize, &curfont, justfctn);
  794.                 if (gImportPBPtr->result) return (0); 
  795.                 if (frmtlent == (frmtcnt + 1) * 6) 
  796.                     srchlmt = (long)gParagDLent;
  797.                 else {
  798.                     srchlmt = (long) *(short *)gCurrentFormat;
  799.                     gCurrentFormat += 2;
  800.                 }
  801.                 tmpstrpos = gImportPBPtr->textBuffer;
  802.                 while (tmpstrpos - gImportPBPtr->textBuffer < (long)256 && 
  803.                                                   gParagPos - gParagraph < srchlmt)
  804.                     *tmpstrpos++ = *gParagPos++;
  805.  
  806.                 if ((gParagPos - gParagraph) != srchlmt) 
  807.                     gImportPBPtr->translatorState = kSameSrch;
  808.                 *size = cursize;
  809.                 *face = curface;
  810.                 *font = curfont;
  811.                 return ((short)(tmpstrpos - gImportPBPtr->textBuffer));
  812.             } else {
  813.                 frmtcnt++;
  814.                 cursize = (short) *gCurrentFormat++;
  815.                 curface = (short) *gCurrentFormat++;
  816.                 curfont = *(short *)gCurrentFormat;
  817.                 gCurrentFormat += 2;
  818.  
  819.                 if (frmtlent == (frmtcnt + 1) * 6) 
  820.                     srchlmt = (long)gParagDLent;
  821.                 else {
  822.                     srchlmt = (long) *(short *)gCurrentFormat;
  823.                     gCurrentFormat += 2;
  824.                 }
  825.                 tmpstrpos = gImportPBPtr->textBuffer;
  826.                 for (; ((tmpstrpos - gImportPBPtr->textBuffer) < (long)256) && 
  827.                                                 ((gParagPos - gParagraph) < srchlmt);)
  828.                     *tmpstrpos++ = *gParagPos++;
  829.  
  830.                 if ((gParagPos - gParagraph) != srchlmt) 
  831.                     gImportPBPtr->translatorState = kSameSrch;
  832.                 *size = cursize;
  833.                 *face = curface;
  834.                 *font = curfont;
  835.                 return ((short)(tmpstrpos - gImportPBPtr->textBuffer));
  836.             }
  837.             break;
  838.  
  839.         case kSameSrch:
  840.             tmpstrpos = gImportPBPtr->textBuffer;
  841.             for (; ((tmpstrpos - gImportPBPtr->textBuffer) < (long)256) && 
  842.                                                 ((gParagPos - gParagraph) < srchlmt);)
  843.                 *tmpstrpos++ = *gParagPos++;
  844.  
  845.             if ((gParagPos - gParagraph) == srchlmt) 
  846.                 gImportPBPtr->translatorState = kNewSrch;
  847.             *size = cursize;
  848.             *face = curface;
  849.             *font = curfont;
  850.             return ((short)(tmpstrpos - gImportPBPtr->textBuffer));
  851.             break;
  852.     }
  853. }
  854.